import {
  ESpecimenStatus,
  ESpeimenTableColumnKey,
  specimenColumns,
} from "@scmt/api-common";
import {
  SpecimenEntity as RawSpecimenEntity,
  SpecimenQueryParams,
} from "@scmt/api-lis-specimen";
import { DataPageProps, TableProps } from "@scmt/common-components";
import { useRequest } from "@scmt/common-hooks";
import { useApi } from "@scmt/core-api";
import { useUtils } from "@scmt/lib-utils";
import {
  useCurrentSpecimen,
  useSelectSpecimens,
  useSpecimenStatus,
} from "./specimen";
import { useStatistics } from "./statistics";
import { useOnPageActions } from "./pageActions";
import { useGroup } from "../../composable/group";

interface SpecimenEntity extends RawSpecimenEntity {
  __destoring?: boolean;
}

const _tableData = reactive({
  items: [] as SpecimenEntity[],
  pagination: {
    total: 0,
    pageNum: 1,
    pageSize: 20,
  },
});

const _loading = ref(false);

export const useData = () => {
  const $api = useApi();
  const $utils = useUtils();

  const { updateCurrentSpecimen, currentSpecimen } = useCurrentSpecimen();
  const { updateSelectSpecimens } = useSelectSpecimens();
  const { specimenStatus } = useSpecimenStatus();
  const { getStatistics } = useStatistics();
  const { onPageActions } = useOnPageActions();
  const { getCellClassName, spanMethod, getGroupKey } = useGroup(
    toRef(_tableData)
  );

  const queryPramas = reactive<SpecimenQueryParams>({
    startDate: $utils.date().startOf("date").format("YYYY-MM-DD HH:mm:ss"),
    endDate: $utils.date().endOf("date").format("YYYY-MM-DD HH:mm:ss"),
    get _tempDate() {
      return [this.startDate, this.endDate];
    },
    set _tempDate(val) {
      [this.startDate, this.endDate] = val || ["", ""];
    },
    pageNum: 1,
    pageSize: 20,
  });

  const { request, loadingMap } = useRequest(
    {
      tableData: async (q?: any) => {
        const { _tempDate, ...params } = Object.assign({}, queryPramas, q);

        getStatistics(params);

        return $api.lis.specimen
          .getSpecimenPageList(
            Object.assign({}, params, {
              state: specimenStatus.value,
            })
          )
          .then((res) => {
            Object.assign(_tableData, res);
            Object.assign(queryPramas, res.pagination);

            return res;
          });
      },
      getSpecimen: (id: string) => {
        return $api.lis.specimen.get(id);
      },
    },
    {
      tableData: _tableData,
    }
  );

  const groupedData = computed(() => groupSpecimen(_tableData.items));

  const queryFields: DataPageProps["queryFields"] = [
    {
      prop: "outpatientNumber",
      label: "业务编号",
    },
    {
      prop: "patientName",
      label: "患者姓名",
    },
    {
      prop: "source",
      label: "业务来源",
      as: "select",
      options: {
        loadMethod: () => $api.dict.item.listAsOptions("patient-type"),
      },
    },
    {
      prop: "billingDepartment",
      label: "开单科室",
      as: "select",
      options: {
        render: "office-table",
        loadMethod: $api.upms.org.listAsOptions,
      },
    },
    {
      prop: "barcode",
      label: "标本条码",
    },
    {
      prop: "specimenTypeId",
      label: "标本类型",
      as: "select",
      options: {
        filterable: true,
        loadMethod: () => {
          return $api.lis.specimen.category.listAsOptions();
        },
      },
    },
    {
      prop: "_tempDate",
      label: "开单时间",
      as: "date",
      options: {
        type: "daterange",
      },
      span: 6,
    },
    {
      prop: "urgent",
      label: "加急",
      as: "checkbox",
      span: 2,
      options: {
        trueValue: 1,
        falseValue: 0,
      },
    },
  ];

  const pageProps = computed<DataPageProps>(() => {
    const props: DataPageProps = {
      loading: _loading.value,
      queryModel: queryPramas,
      queryFields,
      onQuery: getData,
      onAct: onPageActions,
      columns: 6,
      flex: true,
    };

    return props;
  });

  const tableColumns: TableProps["columns"] = [
    {
      prop: "_selection",
      type: "selection",
      label: "序号",
      width: "60px",
    },
    //业务来源
    specimenColumns[ESpeimenTableColumnKey.Source],
    //业务编号
    specimenColumns[ESpeimenTableColumnKey.OutpatientNumber],
    //患者姓名
    specimenColumns[ESpeimenTableColumnKey.PatientName],
    //患者性别
    specimenColumns[ESpeimenTableColumnKey.Sex],
    //患者年龄
    specimenColumns[ESpeimenTableColumnKey.Age],
    //检查项目
    specimenColumns[ESpeimenTableColumnKey.ApplicationProject],
    //标本类型
    specimenColumns[ESpeimenTableColumnKey.SpecimenTypeId],
    {
      prop: "sampleContainer",
      label: "试管名称",
      width: 130,
      render: ({ row }) => {
        let resText = row.sampleContainer;
        return h(
          "div",
          {
            style: {
              width: "100%",
              background: row.sampleContainerColor,
              textAlign: "center",
            },
          },
          resText
        );
      },
    },
    //标本条码
    specimenColumns[ESpeimenTableColumnKey.Barcode],
    //标本状态
    specimenColumns[ESpeimenTableColumnKey.State],
    //开单科室
    specimenColumns[ESpeimenTableColumnKey.BillingDepartment],
    //开单医生
    specimenColumns[ESpeimenTableColumnKey.BillingDoctor],
    //开单时间
    specimenColumns[ESpeimenTableColumnKey.BillingTime],
    {
      prop: "collectionName",
      label: "采集医生",
      tooltip: true,
    },
    {
      prop: "collectionTime",
      label: "采集时间",
      format: "datetime",
      sortable: true,
    },
    //加急
    specimenColumns[ESpeimenTableColumnKey.Urgent],
    //缴费状态
    specimenColumns[ESpeimenTableColumnKey.PaymentStatus],
    {
      prop: "_operation",
      label: "操作",
      fixed: "right",
      width: 200,
      actions: ({ row }) => {
        return [
          {
            label: "标本采集",
            event: "collection",
            type: "primary",
            visible: ESpecimenStatus.PrintedBarCode == row.state,
          },
          {
            label: "标本轨迹",
            event: "check",
            type: "primary",
          },
          {
            event: "destroy",
            visible: row.state === ESpecimenStatus.Cancelled,
            loading: row.__destoring,
          },
        ];
      },
    },
  ];

  const tableProps = computed(() => {
    const tableProps: TableProps = {
      loading: _loading.value,
      data: _tableData.items,
      pagination: _tableData.pagination,
      columns: tableColumns,
      onAct: onPageActions,
      onPaginate: getData,
      onSelectionChange: updateSelectSpecimens,
      onRowDblclick: updateCurrentSpecimen,
      highlightCurrentRow: true,
      cellStyle: ({ row, column }) => {
        if (column.property === "sampleContainer") {
          return {
            background: `${row.sampleContainerColor}!important`,
          };
        }
      },
      cellClassName: getCellClassName,
      spanMethod,
    };
    return tableProps;
  });

  watch(
    () => loadingMap.tableData,
    (val) => {
      _loading.value = val;
    },
    {
      immediate: true,
    }
  );

  const getData = (q?: any) => {
    // 获取列表数据
    request("tableData", {
      params: q,
      onSuccess: (res) => {
        if (currentSpecimen.value) {
          const specimen = res.items.find(
            (item) => item.id === currentSpecimen.value!.id
          );
          if (specimen) {
            updateCurrentSpecimen(specimen);
          } else {
            request("getSpecimen", {
              params: currentSpecimen.value.id,
              onSuccess: (res) => {
                updateCurrentSpecimen(res);
              },
            });
          }
        }
      },
    });
    // 获取统计数据
  };

  // 合管数据
  const groupSpecimen = (source: SpecimenEntity | SpecimenEntity[]) => {
    const entities = ([] as SpecimenEntity[]).concat(source);

    const mergeMap = entities.reduce((acc, cur) => {
      if (!cur.checkId) return acc;

      const key = cur[getGroupKey(cur)];

      if (!Object.prototype.hasOwnProperty.call(acc, key)) {
        acc[key] = [];
      }

      acc[key].push(cur);
      return acc;
    }, {} as Record<string, SpecimenEntity[]>);

    return mergeMap;
  };

  return {
    queryPramas,
    pageProps,
    tableProps,
    tableData: _tableData,
    groupedData,
    getData,
    groupSpecimen,
    getGroupKey,
  };
};
